﻿using System;
using System.Web.Security;
using FluentValidation.TestHelper;
using GiveAQuiz.Web.Helpers;
using GiveAQuiz.Web.Membership;
using GiveAQuiz.Web.Models;
using GiveAQuiz.Web.Validation;
using Moq;
using NUnit.Framework;

namespace GiveAQuiz.Web.Tests.Validation
{
  [TestFixture]
  public class ConfirmRegistrationValidatorTest
  {
    public Mock<IMembershipService> MockMembershipService
    {
      get;
      private set;
    }

    public ConfirmRegistrationValidator Validator
    {
      get;
      private set;
    }

    [TestFixtureSetUp]
    public void InitializeFixture()
    {
      MockMembershipService = new Mock<IMembershipService>();
      MockMembershipService.SetupGet(m => m.MinPasswordLength).Returns(6);
      MockMembershipService.Setup(m => m.GetUser("Foo")).Returns(CreateUser());
      MockMembershipService.Setup(m => m.GetUser("Bar")).Returns(null as MembershipUser);
      Validator = new ConfirmRegistrationValidator(MockMembershipService.Object);
    }

    [Test]
    public void RuleFor_UserName_should_not_have_error_when_username_is_specified()
    {
      Validator.ShouldNotHaveValidationErrorFor(cr => cr.UserName, "Foo");
    }

    [Test]
    public void RuleFor_UserName_should_have_error_when_username_not_found()
    {
      Validator.ShouldHaveValidationErrorFor(cr => cr.UserName, "Bar");
    }

    [Test]
    public void RuleFor_UserName_cannot_be_empty()
    {
      Validator.ShouldHaveValidationErrorFor(cr => cr.UserName, String.Empty);
    }

    [Test]
    public void RuleFor_UserName_cannot_be_null()
    {
      Validator.ShouldHaveValidationErrorFor(cr => cr.UserName, null as string);
    }

    [Test]
    public void RuleFor_UserName_cannot_be_blank()
    {
      Validator.ShouldHaveValidationErrorFor(cr => cr.UserName, "  ");
    }

    [Test]
    public void ValidateToken_should_have_error_when_token_is_null()
    {
      var model = new ConfirmRegistrationViewModel { UserName = "Foo", Token = null };
      Validator.ShouldHaveValidationErrorFor(cr => cr.Token, model);
    }

    [Test]
    public void ValidateToken_should_have_error_when_token_is_empty()
    {
      var model = new ConfirmRegistrationViewModel { UserName = "Foo", Token = String.Empty };
      Validator.ShouldHaveValidationErrorFor(cr => cr.Token, model);
    }

    [Test]
    public void ValidateToken_should_have_error_when_token_is_blank()
    {
      var model = new ConfirmRegistrationViewModel { UserName = "Foo", Token = "   " };
      Validator.ShouldHaveValidationErrorFor(cr => cr.Token, model);
    }

    [Test]
    public void ValidateToken_should_have_error_when_token_is_bad()
    {
      string badToken = "bar@foo.com".ToSHA1Hash().Replace("-", String.Empty);
      var model = new ConfirmRegistrationViewModel { UserName = "Foo", Token = badToken };
      Validator.ShouldHaveValidationErrorFor(cr => cr.Token, model);
    }

    [Test]
    public void ValidateToken_should_not_have_error_when_token_is_correct()
    {
      string badToken = "foo@bar.com".ToSHA1Hash().Replace("-", String.Empty);
      var model = new ConfirmRegistrationViewModel { UserName = "Foo", Token = badToken };
      Validator.ShouldNotHaveValidationErrorFor(cr => cr.Token, model);
    }

    private static MembershipUser CreateUser()
    {
      return new MembershipUser("AspNetSqlMembershipProvider",
        "Foo",
        null,
        "foo@bar.com",
        null,
        null,
        true,
        false,
        DateTime.Now,
        DateTime.Now,
        DateTime.Now,
        DateTime.Now,
        DateTime.MinValue);
    }
  }
}
